﻿#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using UnityEngine;

namespace Ease.EaseNode.Runtime
{
    [Serializable]
    public class CommonEaseNodeInfo : IEaseNodeInfo
    {
        private bool isOnInit = false;
        public event Action OnInit;
        public event Action OnChange;
        private string key;

        [ShowInInspector]
        public string Key
        {
            get => key;
            set
            {
                isOnInit = false;
                key = value;
            }
        }

        protected List<PortConfig> inputConfigs = new List<PortConfig>();

        public List<PortConfig> InputConfigs
        {
            get
            {
                if (isOnInit == false)
                {
                    isOnInit = true;
                    OnInit?.Invoke();
                }

                return inputConfigs;
            }
        }

        protected List<PortConfig> outputConfigs = new List<PortConfig>();

        public List<PortConfig> OutputConfigs
        {
            get
            {
                if (isOnInit == false)
                {
                    isOnInit = true;
                    OnInit?.Invoke();
                }

                return outputConfigs;
            }
        }

        [SerializeField] protected List<PortInfo> inputInfos = new List<PortInfo>();

        //dic:[inputPort.name,{outputPort.name,outputPort2.name}]
        public List<PortInfo> InputInfos
        {
            get
            {
                if (isOnInit == false)
                {
                    isOnInit = true;
                    OnInit?.Invoke();
                }

                return inputInfos;
            }
            set => inputInfos = value;
        }

        //dic:[outputPort.name,{inputPort.name,inputPort2.name}]
        [SerializeField] protected List<PortInfo> outputInfos = new List<PortInfo>();

        public List<PortInfo> OutputInfos
        {
            get
            {
                if (isOnInit == false)
                {
                    isOnInit = true;
                    OnInit?.Invoke();
                }

                return outputInfos;
            }
            set => outputInfos = value;
        }


        [ShowInInspector]
        public List<string> OutputInfos2
        {
            get
            {
                List<string> temp = new List<string>();
                foreach (var outputInfo in outputInfos)
                {
                    temp.Add(outputInfo.ToString());
                }

                return temp;
            }
        }


        public virtual void AddInputInfos(string key, string value)
        {
            var portInfo = InputInfos.FirstOrDefault(x => x.portName.Equals(key));
            if (portInfo != null)
            {
                if (!portInfo.portNames.Contains(value))
                    portInfo.portNames.Add(value);
            }
            else
            {
                var newPortInfo = new PortInfo() { portName = key };
                newPortInfo.portNames.Add(value);
                InputInfos.Add(newPortInfo);
            }

            OnChange?.Invoke();
        }

        public virtual void RemoveInputInfos(string key, string value)
        {
            var portInfo = InputInfos.FirstOrDefault(x => x.portName.Equals(key));
            portInfo?.portNames.Remove(value);
            OnChange?.Invoke();
        }

        public virtual void AddOutputInfos(string key, string value)
        {
            var portInfo = OutputInfos.FirstOrDefault(x => x.portName.Equals(key));
            if (portInfo != null)
            {
                if (!portInfo.portNames.Contains(value))
                    portInfo.portNames.Add(value);
            }
            else
            {
                var newPortInfo = new PortInfo() { portName = key };
                newPortInfo.portNames.Add(value);
                OutputInfos.Add(newPortInfo);
            }

            OnChange?.Invoke();
        }

        public virtual void RemoveOutputInfos(string key, string value)
        {
            var portInfo = OutputInfos.FirstOrDefault(x => x.portName.Equals(key));
            portInfo?.portNames.Remove(value);
            OnChange?.Invoke();
        }

        [SerializeField] [ReadOnly] protected Vector2 nodePos = Vector2.zero;

        public Vector2 NodePos
        {
            get => nodePos;
            set => nodePos = value;
        }
    }
}
#endif